package com.zt.controller;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.zt.mapper.BookingsMapper;
import com.zt.pojo.Bookings;
import com.zt.pojo.Order;
import com.zt.service.MembershipService;
import com.zt.service.OrdersService;
import com.zt.service.impl.AlipayService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/pay/alipay")
public class AlipayController {
    private static final Logger log = LoggerFactory.getLogger(AlipayController.class);

    @Autowired
    private AlipayService alipayService;

    @Autowired
    private OrdersService orderService;
    
    @Autowired
    private MembershipService membershipService;
    
    @Autowired
    private BookingsMapper bookingsMapper;

    /**
     * 创建支付宝订单
     */
    @PostMapping("/create")
    public Map<String, Object> createOrder(@RequestBody Map<String, Object> params) {
        Map<String, Object> result = new HashMap<>();
        try {
            String orderNo = params.get("orderNo").toString();
            BigDecimal amount = new BigDecimal(params.get("amount").toString());
            String subject = params.get("subject") != null ? params.get("subject").toString() : "订单支付-" + orderNo;

            // 调用方法 返回 支付宝的html 页面
            String payHtml = alipayService.createAlipayOrder(orderNo, amount, subject);

            result.put("code", 200);
            result.put("message", "创建订单成功");
            result.put("data", payHtml);
        } catch (Exception e) {
            result.put("code", 500);
            result.put("message", "创建订单失败：" + e.getMessage());
        }
        return result;
    }

    /**
     * 查询支付状态
     */
    @GetMapping("/query/{orderNo}")
    public Map<String, Object> queryPayStatus(@PathVariable String orderNo) {

        Map<String, Object> result = new HashMap<>();
        try {
            boolean isPaid = alipayService.queryPayStatus(orderNo);

            if (isPaid) {
                // 尝试更新普通订单状态为已支付(3)
                // updateOrderStatus方法内部会同时更新关联的预约状态为已支付(1) 
                boolean updated = orderService.updateOrderStatus(orderNo, 3);
                log.info("通过查询API更新订单状态结果：{}, 订单号: {}", updated, orderNo);
                
                // 如果普通订单更新失败，尝试更新会员订单
                if (!updated) {
                    membershipService.updateOrderPayStatus(orderNo);
                }
            }

            result.put("code", 200);
            result.put("message", "查询成功");
            result.put("data", new HashMap<String, Object>() {{
                put("paid", isPaid);
            }});
        } catch (AlipayApiException e) {
            result.put("code", 500);
            result.put("message", "查询失败：" + e.getMessage());
        }
        return result;
    }

    /**
     * 支付宝同步回调 - 支付成功后跳转
     */
    @GetMapping("/success")
    public void handleReturnUrl(HttpServletRequest request, HttpServletResponse response) throws IOException {
        try {
            // 获取支付宝GET过来的参数
            Map<String, String> params = new HashMap<>();
            Map<String, String[]> requestParams = request.getParameterMap();
            for (String name : requestParams.keySet()) {
                String[] values = requestParams.get(name);
                String valueStr = "";
                for (int i = 0; i < values.length; i++) {
                    valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
                }
                params.put(name, valueStr);
            }
            
            // 获取订单号
            String outTradeNo = params.get("out_trade_no");
            log.info("支付宝同步回调，订单号：{}", outTradeNo);
            
            if (outTradeNo != null) {
                // 1. 更新订单状态
                boolean orderUpdated = orderService.updateOrderStatus(outTradeNo, 3);
                log.info("同步回调更新订单状态结果：{}", orderUpdated);
                
                // 2. 直接查找并更新最近的预约状态
                try {
                    Order order = orderService.getOrderByOrderNo(outTradeNo);
                    if (order != null) {
                        // 尝试提取预约ID
                        String bookingIdStr = null;
                        if (outTradeNo.length() > 16) {
                            bookingIdStr = outTradeNo.substring(12, 16);
                        }
                        
                        if (bookingIdStr != null) {
                            try {
                                Integer bookingId = Integer.parseInt(bookingIdStr);
                                log.info("从订单号提取的预约ID: {}", bookingId);
                                
                                // 直接更新预约状态
                                int updatedCount = bookingsMapper.update(
                                    null,
                                    new LambdaUpdateWrapper<Bookings>()
                                        .eq(Bookings::getId, bookingId)
                                        .set(Bookings::getStatus, 1)
                                        .set(Bookings::getUpdateTime, LocalDateTime.now())
                                );
                                log.info("直接更新预约状态结果, bookingId={}, 影响行数={}", bookingId, updatedCount);
                            } catch (Exception e) {
                                log.error("解析预约ID失败", e);
                            }
                        }
                        
                        // 同时根据用户ID更新最近的未支付预约
                        int updatedCount = bookingsMapper.update(
                            null,
                            new LambdaUpdateWrapper<Bookings>()
                                .eq(Bookings::getUserId, order.getUserId())
                                .eq(Bookings::getStatus, 0)
                                .orderByDesc(Bookings::getCreateTime)
                                .last("LIMIT 1")
                                .set(Bookings::getStatus, 1)
                                .set(Bookings::getUpdateTime, LocalDateTime.now())
                        );
                        log.info("更新用户最近未支付预约状态，userId={}, 影响行数={}", order.getUserId(), updatedCount);
                    }
                } catch (Exception e) {
                    log.error("回调中更新预约状态失败", e);
                }
            }
            
            // 设置响应类型
            response.setContentType("text/html;charset=utf-8");
            
            // 返回HTML内容，用于在支付宝webview内跳转到小程序内的页面
            String html = "<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">"
                    + "<title>支付完成</title><style>body{font-family:Arial,sans-serif;display:flex;flex-direction:column;align-items:center;justify-content:center;height:100vh;margin:0;background:#f5f5f5;}.container{text-align:center;padding:20px;background:white;border-radius:10px;box-shadow:0 2px 10px rgba(0,0,0,0.1);}.success-icon{color:#52c41a;font-size:80px;margin-bottom:20px;}.button{background:#1890ff;color:white;border:none;padding:10px 20px;border-radius:4px;font-size:16px;cursor:pointer;margin-top:20px;}</style>"
                    + "</head><body><div class=\"container\"><div class=\"success-icon\">✓</div><h1>支付成功</h1>"
                    + "<p>您的订单已支付完成</p>"
                    + "<button class=\"button\" onclick=\"goToApp()\">返回应用</button></div>"
                    + "<script>function goToApp() {window.location.href = 'wxapplet://order?action=view';}</script></body></html>";
            
            response.getWriter().write(html);
        } catch (Exception e) {
            log.error("处理同步回调异常", e);
            response.sendRedirect("wxapplet://order?action=view");
        }
    }

    /**
     * 支付宝异步通知
     */
    @PostMapping("/notify")
    public String handleAlipayNotify(HttpServletRequest request) {
        System.out.println("======回调方法执行======");
        Map<String, String> params = new HashMap<>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (String name : requestParams.keySet()) {            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            params.put(name, valueStr);
        }
        log.info("支付宝异步通知参数: {}", JSON.toJSONString(params));

        try {
            // 验证签名
            boolean signVerified = alipayService.verifyNotify(params);

            if (signVerified) {
                // 商户订单号
                String outTradeNo = params.get("out_trade_no");
                // 支付宝交易号
                String tradeNo = params.get("trade_no");
                // 交易状态
                String tradeStatus = params.get("trade_status");

                log.info("接收到支付宝异步通知，订单号：{}，交易状态：{}", outTradeNo, tradeStatus);

                if ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)) {
                    // 先尝试更新普通订单状态为已支付(3)
                    // updateOrderStatus方法内部会同时更新关联的预约状态为已支付(1)
                    boolean updated = orderService.updateOrderStatus(outTradeNo, 3);
                    log.info("更新订单状态结果：{}, 订单号: {}", updated, outTradeNo);
                    
                    // 直接更新预约状态 - 额外保证
                    try {
                        Order order = orderService.getOrderByOrderNo(outTradeNo);
                        if (order != null) {
                            // 尝试提取预约ID
                            String bookingIdStr = null;
                            if (outTradeNo.length() > 16) {
                                bookingIdStr = outTradeNo.substring(12, 16);
                            }
                            
                            if (bookingIdStr != null) {
                                try {
                                    Integer bookingId = Integer.parseInt(bookingIdStr);
                                    log.info("从订单号提取的预约ID: {}", bookingId);
                                    
                                    // 直接更新预约状态
                                    int updatedCount = bookingsMapper.update(
                                        null,
                                        new LambdaUpdateWrapper<Bookings>()
                                            .eq(Bookings::getId, bookingId)
                                            .set(Bookings::getStatus, 1)
                                            .set(Bookings::getUpdateTime, LocalDateTime.now())
                                    );
                                    log.info("异步通知直接更新预约状态结果, bookingId={}, 影响行数={}", bookingId, updatedCount);
                                } catch (Exception e) {
                                    log.error("异步通知解析预约ID失败", e);
                                }
                            }
                            
                            // 同时根据用户ID更新最近的未支付预约
                            int updatedCount = bookingsMapper.update(
                                null,
                                new LambdaUpdateWrapper<Bookings>()
                                    .eq(Bookings::getUserId, order.getUserId())
                                    .eq(Bookings::getStatus, 0)
                                    .orderByDesc(Bookings::getCreateTime)
                                    .last("LIMIT 1")
                                    .set(Bookings::getStatus, 1)
                                    .set(Bookings::getUpdateTime, LocalDateTime.now())
                            );
                            log.info("异步通知更新用户最近未支付预约状态，userId={}, 影响行数={}", order.getUserId(), updatedCount);
                        }
                    } catch (Exception e) {
                        log.error("异步通知中更新预约状态失败", e);
                    }
                    
                    // 如果普通订单更新失败，尝试更新会员订单
                    if (!updated) {
                        log.info("尝试更新会员订单状态，订单号：{}", outTradeNo);
                        membershipService.updateOrderPayStatus(outTradeNo);
                    }
                    
                    return "success";
                }
            }

        } catch (AlipayApiException e) {
            log.error("处理支付宝通知失败", e);
        }

        return "failure";
    }

    /**
     * 手动触发更新预约状态的接口
     */
    @GetMapping("/update-booking/{bookingId}")
    public Map<String, Object> manualUpdateBookingStatus(@PathVariable Integer bookingId) {
        Map<String, Object> result = new HashMap<>();
        try {
            log.info("收到手动更新预约状态请求，预约ID: {}", bookingId);
            
            // 直接更新预约状态为已支付(1)
            Bookings booking = new Bookings();
            booking.setId(bookingId);
            booking.setStatus(1);
            booking.setUpdateTime(LocalDateTime.now());
            
            int updated = bookingsMapper.updateById(booking);
            log.info("手动更新预约状态结果: {}", updated);
            
            result.put("code", 200);
            result.put("message", "操作成功");
            result.put("data", updated > 0);
        } catch (Exception e) {
            log.error("手动更新预约状态失败", e);
            result.put("code", 500);
            result.put("message", "更新失败: " + e.getMessage());
        }
        return result;
    }
} 